fix(destination-motherduck): serialize JSON array columns to avoid empty STRUCT failure#82244
Conversation
…pty STRUCT failure Co-Authored-By: bot_apk <apk@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Co-Authored-By: bot_apk <apk@cognition.ai>
👋 Greetings, Airbyte Team Member!Here are some helpful tips and reminders for your convenience. 💡 Show Tips and TricksPR Slash CommandsAirbyte Maintainers (that's you!) can execute the following slash commands on your PR:
📚 Show Repo GuidanceHelpful Resources
|
Detected
|
|
|
Deploy preview for airbyte-docs ready!
Deployed with vercel-action |
What
Fixes MotherDuck destination sync failures when an
array-typed field contains an empty object (e.g.[{}]), which surface as:This is the failure reported for the Shopify
ordersstream (line_items,refunds,fulfillments,tax_lines, etc. — alltype: ["null","array"]withitems: object).Related to https://github.com/airbytehq/oncall/issues/13118:
How
_serialize_object_columns()(indestination_motherduck/processors/duckdb.py) pre-serializes columns to JSON strings so PyArrow does not infer struct types that DuckDB rejects on empty structs. Previously it only handled columns whose JSON-schematypewas"object", skippingarraycolumns. When an array column contained empty objects, PyArrow inferredlist<struct<>>(list of fieldless structs), which DuckDB'sregister()/INSERT rejects.The gate is now based on the destination SQL column type rather than the raw schema type:
In the CDK type mapping (
airbyte_cdk/sql/types.py), bothobjectandarraymap to the SQLJSONtype, so both are now serialized;vector_arraymaps to a native SQLARRAYand is correctly left untouched. List values (not just dicts) are now serialized, andNone/scalar values pass through unchanged.Declarative-First Evaluation
Not applicable —
destination-motherduckis a Python CDK connector (language:python,cdk:python), not a declarative/manifest connector.Test Coverage
unit_tests/test_serialize_object_columns.py: parametrized coverage of_serialize_object_columns(object, array-of-objects, array-of-scalars, nulls, scalar passthrough, non-schema Airbyte columns) plus a regression test that builds the PyArrow table from an array-of-empty-objects column and registers it in an in-memory DuckDB — this reproduces the reported error without the fix and passes with it.integration_tests/integration_test.pytest_writewith anarray_of_objects_keyfield containing[{}]/[{"a": 1}, {}], exercising the full write path end-to-end (runs against a local DuckDB file in CI).Both suites pass locally (
poetry run pytest unit_tests/→ 53 passed;test_write[local_file_config]andtest_write_dupe[local_file_config]pass).Review guide
airbyte-integrations/connectors/destination-motherduck/destination_motherduck/processors/duckdb.py— the fixairbyte-integrations/connectors/destination-motherduck/unit_tests/test_serialize_object_columns.py— new testsairbyte-integrations/connectors/destination-motherduck/integration_tests/integration_test.py— extended coverageUser Impact
Syncs to MotherDuck with array fields that contain empty objects (e.g. Shopify
orders) will no longer fail in the destination write stage. Non-breaking bug fix; patch bump0.2.4→0.2.5-rc.1(progressive rollout is enabled on this connector, so the-rc.1suffix is required).Can this PR be safely reverted and rolled back?
Link to Devin session: https://app.devin.ai/sessions/b5a2e996760a4d5f9157915b4fe0d2cb
Important
Active progressive rollout warning for destination-motherduck.